package com.cloud.custom.tasklist.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.custom.common.result.QkIcon;
import com.cloud.custom.common.result.QkTreeNode;
import com.cloud.custom.common.utils.SessionHelper;
import com.cloud.custom.tasklist.bean.MenuTabAuthority;
import com.cloud.custom.tasklist.bean.Part;
import com.cloud.custom.tasklist.bean.TabMenuHeader;
import com.cloud.custom.tasklist.entity.TaskListMenuPart;
import com.cloud.custom.tasklist.entity.TaskListMenu;
import com.cloud.custom.tasklist.entity.TaskListMenuGroup;
import com.cloud.custom.tasklist.mapper.TaskListMenuPartMapper;
import com.cloud.custom.tasklist.mapper.TaskListMenuGroupMapper;
import com.cloud.custom.tasklist.mapper.TaskListMenuMapper;
import com.cloud.custom.tasklist.service.TaskListMenuService;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class TaskListMenuServiceImpl implements TaskListMenuService {

	@Autowired
	private TaskListMenuGroupMapper taskListMenuGroupMapper;
	@Autowired
	private TaskListMenuMapper taskListMenuMappler;
	@Autowired
	private TaskListMenuPartMapper menuPartMapper;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<QkTreeNode> listTree() {
		Example grpExample = new Example(TaskListMenuGroup.class);
		Example.Criteria grpCriteria = grpExample.createCriteria();
		grpCriteria.andEqualTo("deleteFlag", 0);
		grpExample.orderBy("displayOrder").asc();
		List<TaskListMenuGroup> groups = taskListMenuGroupMapper.selectByExample(grpExample);
		Example menuExample = new Example(TaskListMenu.class);
		Example.Criteria menuCriteria = menuExample.createCriteria();
		menuCriteria.andEqualTo("deleteFlag", 0);
		menuExample.orderBy("displayOrder").asc();
		List<TaskListMenu> menus = taskListMenuMappler.selectByExample(menuExample);
		List<QkTreeNode> nodes = new ArrayList<QkTreeNode>();
		for (TaskListMenuGroup group : groups) {
			QkTreeNode grpNode = new QkTreeNode("grp_" + group.getGroupId(), group.getGroupName());
			grpNode.setCollapsedIcon(QkIcon.FA_FOLDER);
			grpNode.setExpandedIcon(QkIcon.FA_FOLDER_OPEN);
			grpNode.setRootFlag(true);
			grpNode.setSelectable(true);
			grpNode.setExpanded(true);
			for (TaskListMenu menu : menus) {
				if (menu.getGroupId().equals(group.getGroupId())) {
					QkTreeNode menuNode = new QkTreeNode(menu.getMenuId(), menu.getMenuName());
					menuNode.setSeniorId("grp_" + group.getGroupId());
					menuNode.setSelectable(true);
					menuNode.setLeaf(true);
					menuNode.setIcon(QkIcon.FA_LAPTOP);
					grpNode.getChildren().add(menuNode);
				}
			}
			nodes.add(grpNode);
		}
		return nodes;
	}

	@Override
	public List<TabMenuHeader> listTaskListMenuHeader() {
		Example grpExample = new Example(TaskListMenuGroup.class);
		grpExample.orderBy("displayOrder").asc();
		List<TaskListMenuGroup> groups = taskListMenuGroupMapper.selectByExample(grpExample);
		Example menuExample = new Example(TaskListMenu.class);
		menuExample.orderBy("displayOrder").asc();
		List<TaskListMenu> menus = taskListMenuMappler.selectByExample(menuExample);

		List<TabMenuHeader> results = new ArrayList<TabMenuHeader>();
		for (TaskListMenuGroup grp : groups) {
			TabMenuHeader father = new TabMenuHeader();
			father.setId(grp.getGroupId());
			father.setHeader(grp.getGroupName());
			father.setField(grp.getGroupName());
			for (TaskListMenu menu : menus) {
				if (menu.getGroupId().equals(grp.getGroupId())) {
					TabMenuHeader child = new TabMenuHeader();
					child.setId(menu.getMenuId());
					child.setHeader(menu.getMenuName());
					child.setField(menu.getMenuId() + "");
					child.setWidth(100);
					father.getChildren().add(child);
				}
			}
			if (father.getChildren().size() > 0) {
				father.setWidth(father.getChildren().size() * 100);
				results.add(father);
			}
		}
		return results;
	}

	@Override
	public void saveUpdatePartAuth(List<MenuTabAuthority> parts, long actDefId, long taskListId) {
		Example exp = new Example(TaskListMenuPart.class);
		Example.Criteria criteria = exp.createCriteria();
		criteria.andEqualTo("taskListId", taskListId);
		criteria.andEqualTo("actDefId", actDefId);
		menuPartMapper.deleteByExample(exp);
		List<TaskListMenuPart> partMenus = new ArrayList<TaskListMenuPart>();
		for (MenuTabAuthority part : parts) {
			TaskListMenuPart tPart = new TaskListMenuPart();
			tPart.setTaskListId(taskListId);
			tPart.setActDefId(actDefId);
			tPart.setPartId(part.getPartId());
			tPart.setMenuId(part.getMenuTabId());
			tPart.setAuthCode(part.getCode());
			partMenus.add(tPart);
		}
		final List<TaskListMenuPart> pts = partMenus;
		jdbcTemplate.batchUpdate(
				"insert into task_list_menu_part(task_list_id, act_def_id, part_id, menu_id, auth_code) values (?, ?, ?, ?, ?)",
				new BatchPreparedStatementSetter() {
					@Override
					public void setValues(PreparedStatement ps, int i) throws SQLException {
						TaskListMenuPart p = pts.get(i);
						ps.setLong(1, p.getTaskListId());
						ps.setLong(2, p.getActDefId());
						ps.setLong(3, p.getPartId());
						ps.setLong(4, p.getMenuId());
						ps.setInt(5, p.getAuthCode());
					}

					@Override
					public int getBatchSize() {
						return pts.size();
					}
				});

	}

	@Override
	public List<Part> listPartAuthority(long taskListId, long actDefId, List<Part> parts) {
		Example example = new Example(TaskListMenu.class);
		example.orderBy("displayOrder").asc();
		List<TaskListMenu> menus = taskListMenuMappler.selectByExample(example);
		// 先设置所有的tab为默认权限
		for (Part p : parts) {
			for (TaskListMenu menu : menus) {
				p.getAuths().put(menu.getMenuId(), 0);
			}
		}
		// 设置所有参与者配置的权限
		Example menuPartsExample = new Example(TaskListMenuPart.class);
		Example.Criteria tpCriteria = menuPartsExample.createCriteria();
		tpCriteria.andEqualTo("actDefId", actDefId);
		tpCriteria.andEqualTo("taskListId", taskListId);
		List<TaskListMenuPart> menuParts = menuPartMapper.selectByExample(menuPartsExample);

		// 配置权限优先于默认权限
		for (Part p : parts) {
			Map<Long, Integer> auths = p.getAuths();
			for (TaskListMenuPart tp : menuParts) {
				if (tp.getPartId().equals(p.getPartId())) {
					auths.put(tp.getMenuId(), tp.getAuthCode());
				}
			}
		}
		return parts;
	}

	@Override
	public List<TaskListMenu> listTaskListMenuByPart(long taskListId, long actDefId, Integer poz) {
		// 环节权限配置菜单
		Set<Long> menuIds = new HashSet<Long>();
		if (actDefId != 0) {
			Example example = new Example(TaskListMenuPart.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("taskListId", taskListId);
			criteria.andIn("actDefId", Arrays.asList(new Long[] { 0L, actDefId }));
			criteria.andEqualTo("authCode", 1);
			criteria.andIn("partId", SessionHelper.get().getParts());
			List<TaskListMenuPart> menuParts = menuPartMapper.selectByExample(example);
			for (TaskListMenuPart mp : menuParts) {
				menuIds.add(mp.getMenuId());
			}
		}
		// 环节无关，人有的菜单
		List<Long> menus = menuPartMapper.loadUnActMenu(taskListId, SessionHelper.get().getParts());
		menuIds.addAll(menus);

		if (menuIds.size() > 0) {
			Example menuExample = new Example(TaskListMenu.class);
			Example.Criteria menuCriteria = menuExample.createCriteria();
			menuCriteria.andIn("menuId", menuIds);
			menuExample.orderBy("displayOrder");
			List<TaskListMenu> authMenus = taskListMenuMappler.selectByExample(menuExample);
			if (null != poz) {
				List<TaskListMenu> results = new ArrayList<TaskListMenu>(authMenus.size());
				for (TaskListMenu m : authMenus) {
					if ((m.getPozAttr() & poz) == poz) {
						results.add(m);
					}
				}
				return results;
			} else {
				return authMenus;
			}
		}
		return null;
	}

	@Override
	public long saveUpdateGroup(TaskListMenuGroup group) {
		if (null == group.getGroupId() || 0 == group.getGroupId()) {
			group.setDeleteFlag(0);
			taskListMenuGroupMapper.insert(group);
		} else {
			group.setDeleteFlag(0);
			taskListMenuGroupMapper.updateByPrimaryKey(group);
		}
		return group.getGroupId();
	}

	@Override
	public void deleteGroup(long groupId) {
		TaskListMenuGroup group = taskListMenuGroupMapper.selectByPrimaryKey(groupId);
		group.setDeleteFlag(1);
		taskListMenuGroupMapper.updateByPrimaryKey(group);
	}

	@Override
	public TaskListMenu saveUpdateTaskListMenu(TaskListMenu menu) {
		if (null == menu.getMenuId() || 0 == menu.getMenuId()) {
			// 新增
			menu.setDeleteFlag(0);
			taskListMenuMappler.insert(menu);
		} else {
			menu.setDeleteFlag(0);
			taskListMenuMappler.updateByPrimaryKey(menu);
		}
		return menu;
	}

	@Override
	public long deleteMenu(long menuId) {
		TaskListMenu menu = taskListMenuMappler.selectByPrimaryKey(menuId);
		menu.setDeleteFlag(1);
		taskListMenuMappler.updateByPrimaryKey(menu);
		return menuId;
	}

	@Override
	public TaskListMenu loadMenu(long menuId) {
		return taskListMenuMappler.selectByPrimaryKey(menuId);
	}

}
